// utils/auth.js
const { request } = require('./request')
const { formatTime } = require('./util')

const app = getApp()

// 用户信息接口（注释掉，改为JSDoc）
/**
 * @typedef {Object} UserInfo
 * @property {string} id
 * @property {string} openid
 * @property {string} [unionid]
 * @property {string} nickname
 * @property {string} avatar
 * @property {number} gender
 * @property {string} country
 * @property {string} province
 * @property {string} city
 * @property {string} language
 * @property {string} [phone]
 * @property {string} [email]
 * @property {string} [birthday]
 * @property {string} [signature]
 * @property {boolean} isVip
 * @property {string} [vipExpireTime]
 * @property {string} createTime
 * @property {string} updateTime
 * @property {string} lastLoginTime
 */

/*
/**
 * 用户信息接口
 * @typedef {Object} UserInfo
 * @property {string} id
 * @property {string} openid
 * @property {string} unionid
 * @property {string} nickname
 * @property {string} avatar
 * @property {number} gender
 * @property {string} country
 * @property {string} province
 * @property {string} city
 * @property {string} language
 * @property {string} phone
 * @property {string} email
 * @property {string} birthday
 * @property {string} signature
 * @property {boolean} isVip
 * @property {string} vipExpireTime
 * @property {string} createTime
 * @property {string} updateTime
 * @property {string} lastLoginTime
 */

// 登录响应接口（注释掉）
/**
 * @typedef {Object} LoginResponse
 * @property {string} token
 * @property {string} refreshToken
 * @property {number} expiresIn
 * @property {UserInfo} userInfo
 */

/**
 * @typedef {Object} WxUserInfo
 * @property {string} nickName
 * @property {string} avatarUrl
 * @property {number} gender
 * @property {string} country
 * @property {string} province
 * @property {string} city
 * @property {string} language
 */

class AuthManager {
  constructor() {
    this.loginPromise = null
    this.refreshPromise = null
    this.checkingLogin = false
  }

  static getInstance() {
    if (!AuthManager.instance) {
      AuthManager.instance = new AuthManager()
    }
    return AuthManager.instance
  }

  // 检查登录状态
  async checkLoginStatus() {
    if (this.checkingLogin) {
      return false
    }

    try {
      this.checkingLogin = true
      
      // 检查本地token
      const token = wx.getStorageSync('token')
      const expiresIn = wx.getStorageSync('tokenExpiresIn')
      
      if (!token || !expiresIn) {
        return false
      }
      
      // 检查token是否过期
      const now = Date.now()
      if (now >= expiresIn) {
        // 尝试刷新token
        const refreshToken = wx.getStorageSync('refreshToken')
        if (refreshToken) {
          try {
            await this.refreshAccessToken()
            return true
          } catch (error) {
            console.error('刷新token失败:', error)
            this.clearAuthData()
            return false
          }
        }
        return false
      }
      
      // 验证token有效性
      try {
        const response = await request.get('/api/auth/verify', {}, {
          showLoading: false,
          showError: false
        })
        
        if (response.code === 200) {
          // 更新用户信息
          app.globalData.userInfo = response.data
          app.globalData.token = token
          return true
        } else {
          this.clearAuthData()
          return false
        }
      } catch (error) {
        console.error('验证token失败:', error)
        this.clearAuthData()
        return false
      }
    } catch (error) {
      console.error('检查登录状态失败:', error)
      return false
    } finally {
      this.checkingLogin = false
    }
  }

  // 微信登录
  async wxLogin() {
    // 如果正在登录，返回现有的Promise
    if (this.loginPromise) {
      return this.loginPromise
    }

    this.loginPromise = this.performWxLogin()
    
    try {
      const result = await this.loginPromise
      return result
    } finally {
      this.loginPromise = null
    }
  }

  // 执行微信登录
  async performWxLogin() {
    try {
      // 1. 获取微信登录code
      const loginResult = await this.getWxLoginCode()
      
      // 2. 获取用户信息（如果需要）
      let userProfile = null
      try {
        userProfile = await this.getUserProfile()
      } catch (error) {
        console.warn('获取用户信息失败，使用默认信息:', error)
      }
      
      // 3. 调用后端登录接口
      const response = await request.post('/api/auth/wx-login', {
        code: loginResult.code,
        userInfo: userProfile
      })
      
      if (response.code !== 200) {
        throw new Error(response.message || '登录失败')
      }
      
      // 4. 保存认证信息
      await this.saveAuthData(response.data)
      
      return response.data
    } catch (error) {
      console.error('微信登录失败:', error)
      throw error
    }
  }

  // 获取微信登录code
  getWxLoginCode() {
    return new Promise((resolve, reject) => {
      wx.login({
        success: resolve,
        fail: reject
      })
    })
  }

  // 获取用户信息
  getUserProfile() {
    return new Promise((resolve, reject) => {
      wx.getUserProfile({
        desc: '用于完善用户资料',
        success: (res) => {
          resolve(res.userInfo)
        },
        fail: reject
      })
    })
  }

  // 保存认证数据
  async saveAuthData(loginData) {
    try {
      const expiresIn = Date.now() + (loginData.expiresIn * 1000)
      
      // 保存到本地存储
      wx.setStorageSync('token', loginData.token)
      wx.setStorageSync('refreshToken', loginData.refreshToken)
      wx.setStorageSync('tokenExpiresIn', expiresIn)
      wx.setStorageSync('userInfo', loginData.userInfo)
      
      // 保存到全局数据
      app.globalData.token = loginData.token
      app.globalData.userInfo = loginData.userInfo
      
      console.log('认证数据保存成功')
    } catch (error) {
      console.error('保存认证数据失败:', error)
      throw error
    }
  }

  // 清除认证数据
  clearAuthData() {
    try {
      // 清除本地存储
      wx.removeStorageSync('token')
      wx.removeStorageSync('refreshToken')
      wx.removeStorageSync('tokenExpiresIn')
      wx.removeStorageSync('userInfo')
      
      // 清除全局数据
      app.globalData.token = ''
      app.globalData.userInfo = null
      
      console.log('认证数据清除成功')
    } catch (error) {
      console.error('清除认证数据失败:', error)
    }
  }

  // 刷新访问令牌
  async refreshAccessToken() {
    // 如果正在刷新，返回现有的Promise
    if (this.refreshPromise) {
      return this.refreshPromise
    }

    this.refreshPromise = this.performRefreshToken()
    
    try {
      const result = await this.refreshPromise
      return result
    } finally {
      this.refreshPromise = null
    }
  }

  // 执行刷新令牌
  async performRefreshToken() {
    try {
      const refreshToken = wx.getStorageSync('refreshToken')
      
      if (!refreshToken) {
        throw new Error('没有刷新令牌')
      }
      
      const response = await request.post('/api/auth/refresh', {
        refreshToken
      }, {
        showLoading: false,
        showError: false
      })
      
      if (response.code !== 200) {
        throw new Error(response.message || '刷新令牌失败')
      }
      
      // 保存新的token
      const expiresIn = Date.now() + (response.data.expiresIn * 1000)
      wx.setStorageSync('token', response.data.token)
      wx.setStorageSync('tokenExpiresIn', expiresIn)
      app.globalData.token = response.data.token
      
      return response.data.token
    } catch (error) {
      console.error('刷新令牌失败:', error)
      this.clearAuthData()
      throw error
    }
  }

  // 退出登录
  async logout() {
    try {
      // 调用后端退出接口
      await request.post('/api/auth/logout', {}, {
        showLoading: false,
        showError: false
      })
    } catch (error) {
      console.error('调用退出接口失败:', error)
    } finally {
      // 清除本地数据
      this.clearAuthData()
    }
  }

  // 更新用户信息
  async updateUserInfo(userInfo) {
    try {
      const response = await request.put('/api/user/profile', userInfo)
      
      if (response.code !== 200) {
        throw new Error(response.message || '更新用户信息失败')
      }
      
      // 更新本地用户信息
      const updatedUserInfo = { ...app.globalData.userInfo, ...response.data }
      app.globalData.userInfo = updatedUserInfo
      wx.setStorageSync('userInfo', updatedUserInfo)
      
      return updatedUserInfo
    } catch (error) {
      console.error('更新用户信息失败:', error)
      throw error
    }
  }

  // 绑定手机号
  async bindPhone(phoneCode) {
    try {
      const response = await request.post('/api/user/bind-phone', {
        code: phoneCode
      })
      
      if (response.code !== 200) {
        throw new Error(response.message || '绑定手机号失败')
      }
      
      // 更新用户信息
      if (app.globalData.userInfo) {
        app.globalData.userInfo.phone = response.data.phone
        wx.setStorageSync('userInfo', app.globalData.userInfo)
      }
    } catch (error) {
      console.error('绑定手机号失败:', error)
      throw error
    }
  }

  // 获取用户信息
  getUserInfo() {
    return app.globalData.userInfo || wx.getStorageSync('userInfo') || null
  }

  // 获取token
  getToken() {
    return app.globalData.token || wx.getStorageSync('token') || ''
  }

  // 检查是否已登录
  isLoggedIn() {
    const token = this.getToken();
    const expiresIn = wx.getStorageSync('tokenExpiresIn');
    
    // 兼容不同的存储方式
    const userInfo = this.getUserInfo();
    const user = wx.getStorageSync('user');
    
    // 检查多种可能的登录状态存储方式
    if (!token || !expiresIn || (!userInfo && !user)) {
      return false;
    }
    
    // 检查token是否过期
    return Date.now() < expiresIn;
  }

  // 检查是否需要登录
  async requireLogin() {
    if (this.isLoggedIn()) {
      return true
    }
    
    try {
      await this.wxLogin()
      return true
    } catch (error) {
      console.error('登录失败:', error)
      
      // 显示登录失败提示
      wx.showModal({
        title: '登录失败',
        content: '请重新尝试登录',
        showCancel: false,
        success: () => {
          wx.navigateBack()
        }
      })
      
      return false
    }
  }

  // 检查VIP状态
  isVip() {
    const userInfo = this.getUserInfo()
    if (!userInfo || !userInfo.isVip) {
      return false
    }
    
    if (userInfo.vipExpireTime) {
      return new Date(userInfo.vipExpireTime) > new Date()
    }
    
    return true
  }

  // 获取VIP到期时间
  getVipExpireTime() {
    const userInfo = this.getUserInfo()
    if (!userInfo || !userInfo.vipExpireTime) {
      return null
    }
    
    return formatTime(new Date(userInfo.vipExpireTime), 'YYYY-MM-DD')
  }

  // 检查用户角色
  getUserRole() {
    const userInfo = this.getUserInfo()
    return userInfo?.role || null
  }
  
  // 检查是否为管理员
  isAdmin() {
    return this.getUserRole() === 'admin'
  }
  
  // 检查是否为伴侣
  isPartner() {
    return this.getUserRole() === 'partner'
  }
  
  // 检查是否已设置角色
  hasRole() {
    const role = this.getUserRole()
    return role === 'admin' || role === 'partner'
  }
  
  // 验证管理员密码
  async validateAdminPassword(password) {
    if (!this.isAdmin()) {
      return false
    }
    
    try {
      const response = await request({
        url: '/api/user-role/validate-password',
        method: 'POST',
        data: { password }
      })
      return response.success
    } catch (error) {
      console.error('验证管理员密码失败:', error)
      return false
    }
  }
  
  // 检查权限
  checkPermission(permission) {
    const userInfo = this.getUserInfo()
    if (!userInfo) {
      return false
    }
    
    // 角色权限检查
    switch (permission) {
      case 'create_capsule':
        return true // 所有用户都可以创建胶囊
      case 'unlimited_capsules':
        return this.isVip() // VIP用户可以创建无限胶囊
      case 'export_capsule':
        return this.isVip() // VIP用户可以导出胶囊
      case 'advanced_search':
        return this.isVip() // VIP用户可以使用高级搜索
      case 'admin_access':
        return this.isAdmin() // 管理员权限
      case 'final_answer_access':
        return this.isAdmin() // 最终答案访问权限
      case 'user_management':
        return this.isAdmin() // 用户管理权限
      case 'system_settings':
        return this.isAdmin() // 系统设置权限
      case 'partner_access':
        return this.isPartner() // 伴侣权限
      case 'mood_diary_access':
        return this.hasRole() // 需要有角色才能访问心情日记
      case 'health_tracking':
        return this.hasRole() // 需要有角色才能访问健康追踪
      default:
        return false
    }
  }
}

// 创建认证管理器实例
const authManager = AuthManager.getInstance()

// 导出认证相关方法
const auth = {
  // 检查登录状态
  checkLoginStatus: () => authManager.checkLoginStatus(),
  
  // 微信登录
  wxLogin: () => authManager.wxLogin(),
  
  // 退出登录
  logout: () => authManager.logout(),
  
  // 更新用户信息
  updateUserInfo: (userInfo) => authManager.updateUserInfo(userInfo),
  
  // 绑定手机号
  bindPhone: (phoneCode) => authManager.bindPhone(phoneCode),
  
  // 获取用户信息
  getUserInfo: () => authManager.getUserInfo(),
  
  // 获取token
  getToken: () => authManager.getToken(),
  
  // 检查是否已登录
  isLoggedIn: () => authManager.isLoggedIn(),
  
  // 要求登录
  requireLogin: () => authManager.requireLogin(),
  
  // 检查VIP状态
  isVip: () => authManager.isVip(),
  
  // 获取VIP到期时间
  getVipExpireTime: () => authManager.getVipExpireTime(),
  
  // 检查权限
  checkPermission: (permission) => authManager.checkPermission(permission),
  
  // 清除认证数据
  clearAuthData: () => authManager.clearAuthData(),
  
  // 角色相关方法
  getUserRole: () => authManager.getUserRole(),
  isAdmin: () => authManager.isAdmin(),
  isPartner: () => authManager.isPartner(),
  hasRole: () => authManager.hasRole(),
  validateAdminPassword: (password) => authManager.validateAdminPassword(password)
}

// 导出
module.exports = {
  auth,
  AuthManager
}